home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-15 / mou105.zip / MOU.DOC < prev    next >
Text File  |  1991-09-25  |  23KB  |  537 lines

  1.             Turbo and Microsoft C Mouse Routines - Release 1.05
  2.             ---------------------------------------------------
  3.  
  4. Thu 27-Jan-1991
  5.  
  6. CONTENTS
  7.  
  8.   1. What do these routines do?
  9.   2. How it works.
  10.   3. Variable and definition reference.
  11.   4. Function reference.
  12.   5. The test program.
  13.   6. Disclaimer and other stuff.
  14.   7. Modification history.
  15.  
  16.  
  17. 1. What do these routines do?
  18. -----------------------------
  19.  
  20. These routines will allow you to interface with the mouse driver in your
  21. programs.  It works with Microsoft compatible mouse drivers (i.e. Logitech,
  22. PC Mouse, Dexxa, etc).  The routines have the added feature of displaying a
  23. 'true' mouse cursor in text mode on an EGA or VGA by reprogramming the font
  24. on the fly.
  25.  
  26. The routines consist of several functions used to initialize, draw the
  27. cursor, and get mouse events (button presses).
  28.  
  29. These routines do not handle drawing the mouse cursor in graphics mode,
  30. only text mode.  If the routines detect the presence of an EGA/VGA adapter,
  31. it will use the 'true' mouse cursor, if not it will use a simple block
  32. cursor implemented by switch the foreground/background colors of the
  33. position the cursor is.
  34.  
  35. The routines are distributed in a ZIP file with the following files:
  36.  
  37. MOU.DOC      - This documentation file.
  38. MOU.C        - Turbo C/MSC source code.
  39. MOU.H        - Turbo C/MSC header file.
  40. TEST.C       - Turbo C/MSC test program.
  41. MOU.PAS      - Turbo Pascal unit.
  42. PTEST.PAS    - Turbo Pascal test program.
  43. MAKEFILE     - Makefile for creating TC/MSC versions.
  44. TTEST.EXE    - Turbo C test program.
  45. MTEST.EXE    - Microsoft C test program.
  46. PTEST.EXE    - Turbo Pascal test program.
  47.  
  48. 2. How it works.
  49. ---------------
  50.  
  51. All character coordinates used by the mouse driver are zero based.  I.e. in
  52. 80x25 text mode the range of values for x and y are 0-79 and 0-24.  The
  53. routines should work in all memory models.
  54.  
  55. The routines first check for the presence of a mouse driver, and if none is
  56. present, they return without doing anything.  It is safe to call the
  57. routines such as MOUhide() and others even if a mouse is not installed,
  58. they will simply return.
  59.  
  60. Once the presence of a Microsoft compatible mouse driver is verified, the
  61. routine checks the presence of DESQview and an EGA/VGA.  If an EGA/VGA is
  62. in the system, and the program is not running under DESQview, the routines
  63. will choose to use a 'true' cursor, otherwise a simple block cursor will be
  64. used.  A 'true' cursor is not used under DESQview because DESQview doesn't
  65. really like having it's font changed on the fly by a program.  The 'true'
  66. mouse cursor would probably interfere with other programs running at the
  67. same time.
  68.  
  69. The mouse driver does have a glitch that these routines have to work
  70. around, that being that when in text mode, the mouse driver returns the
  71. coordinates as multiples of 8 (i.e. 0, 8, 16, 24 ...).  Since the 'true'
  72. cursor has a pixel resolution, we need to get the mouse driver to return
  73. coordinates in pixels (i.e. 0, 1, 2, 3 ...).  To do this, we 'trick' the
  74. mouse driver into thinking it is in graphics mode (where coordinates are
  75. returned in pixels) by changing the current video mode.  This is done by
  76. placing a value of 6 in memory location 0x0040:0x0049, 6 being the number
  77. for CGA 640x200 2 color graphics mode.  We then tell the mouse driver to
  78. initialize again (using mouse driver function 0), and the mouse driver
  79. checks the video mode, sees that we are in graphics mode, and sets itself
  80. up accordingly.  We then restore the mode byte at 0x0040:0x0049 to it's
  81. previous value.  After this, the mouse driver returns all coordinates in
  82. pixels.  I had to hack out this fix on my own, I called Microsoft and got
  83. nothing from them, but I remembered that when you are running the mouse
  84. driver in graphics mode on a Hercules graphics adapter, you have to do this
  85. 'trick.'  It worked in this case as well.
  86.  
  87. Next the initialization routine sets up the maximum x and y ranges for the
  88. mouse cursor based on the dimensions of the video mode.  Lastly it installs a
  89. mouse function handler using mouse driver function 12 -- define handler.
  90. The handler is installed for mouse movement, and left or right button
  91. presses and releases.
  92.  
  93. The handler is defined in the function 'void far mousehandler(void)'.  This
  94. function is called by the mouse driver upon one of the events happening as
  95. defined in the call to mouse driver function 12.  The handler will
  96. automatically update the mouse cursor, change the global variables mousex
  97. and mousey to the character (not pixel) coordinates of the mouse.  It also
  98. checks for mouse events (button presses and releases) and stores them into
  99. a buffer if an event happens.  This event is later retrieved with a call to
  100. MOUpreview() or MOUget().
  101.  
  102. The drawing of the mouse cursor on non EGA/VGA adapters is quite simple.
  103. It reverses the foreground and background color of the character where the
  104. mouse is located.  This is the default text cursor that the mouse driver
  105. uses itself.
  106.  
  107. On an EGA/VGA adapter, things get a little more complicated.  A 3x3
  108. character arrangement is used to draw the cursor.  The function
  109. plotegavgacursor() handles saving the 3x3 character array, restoring it
  110. later, and drawing the 3x3 array of characters that is redefined.  The
  111. redefinition consists of reading the definitions of the characters,
  112. preforming an AND and OR of the mouse cursor onto the existing definitions,
  113. then copying those modified definitions to a new location.  I copy to
  114. characters 0xd0 to 0xd8.  Then the characters 0xd0 to 0xd8 are placed in
  115. the 3x3 grid where the mouse cursor is located, thereby drawing the cursor.
  116.  
  117. The mouse cursor is a simple array of dwords (32 bit unsigned long) that is
  118. used to update the character definitions.  The cursor can be changed from
  119. the default one provided, as defined in the mouse driver documentation for
  120. defining graphics cursors.  It consists of two masks:  the screen mask, and
  121. the cursor mask.  The screen mask is bitwise AND'ed to the existing character
  122. definitions, then the cursor mask is bitwise OR'ed to the existing character
  123. definitions.
  124.  
  125. The functions MOUshow(), MOUhide() and MOUconditionalhide() perform as
  126. their counterpart functions provided by the mouse driver.
  127. MOUconditionalhide() is a special function (that some 'clone' drivers
  128. _don't_ have) that allows you to update a rectangular region on the screen
  129. without disturbing the mouse (if it is not in the region).  It is called
  130. with the character coordinates of a rectangular region on the screen.  If
  131. the mouse is in that region, or if the mouse moves into that region, the
  132. mouse cursor will automatically turn off.  A call to MOUshow() cancels the
  133. rectangular region.  You can't make multiple calls to MOUconditionalhide()
  134. between calls to MOUshow().
  135.  
  136. Various 'glitches' arise by using a 'true' mouse cursor.  They are listed
  137. as follows:
  138.  
  139.   1. On the VGA adapter, standard text mode consists of 9 by 16 characters.
  140.      The character are not actually 9 bits wide, but 8.  The VGA duplicates
  141.      the rightmost bit for the border characters (characters 176 to 218).
  142.      The 'true' cursor uses (rather redefines) characters 208 to 216 (0xd0
  143.      to 0xd8 hex), thereby having its rightmost bit duplicated.  If another
  144.      set of characters is used, the cursor appears to have a 'gap' in the
  145.      middle of it.  The problem lies in that if the cursor is moved over a
  146.      character that has some of its rightmost bit set, the rightmost bit
  147.      will be duplicated.  Characters such as the lower case 'm' are
  148.      examples of this.  It is much easier to see the effect of this than
  149.      explain it.  Run the TEST program that comes with the routines and
  150.      place the cursor over a lower case m on the screen.  You will notice
  151.      the effect.  I can't see any way around this.  This doesn't happen on
  152.      an EGA as the EGA uses 8 pixel width characters (not 9).
  153.  
  154.   2. Since the 'true' mouse cursor is larger than one character, moving the
  155.      cursor into areas of the screen with different foreground colors will
  156.      cause the cursor to take on that color.  If the cursor is at the
  157.      border of two different foreground colors, it will appear that the
  158.      cursor is in two colors.  I got around this by always using the same
  159.      foreground color for all characters on the screen (i.e. WHITE) and
  160.      just using different background colors to show differences on the
  161.      screen.
  162.  
  163.   3. DESQview doesn't like its font changed on the fly.  It interferes with
  164.      the 'true' cursor to the point where it's dysfunctional.  The mouse
  165.      routines will automatically detect DESQview and fall back to a normal
  166.      block cursor if running under DV.
  167.  
  168.   4. Since the font is changed, characters 0xd0 to 0xd8 are not available
  169.      for use by the program.  These characters are the IBM border
  170.      characters used to connect double line and single line boxes together.
  171.      I don't use these characters in my programs, and they aren't really
  172.      needed.  If you need to have a single line join a double line graphics
  173.      character, just place them side by side.  They won't actually 'join'
  174.      as it would by using a double to single line character, but they will
  175.      line up closely.  I find it an acceptable loss to provide a 'true'
  176.      mouse cursor on the EGA/VGA.
  177.  
  178. For a description of how to change fonts on the EGA/VGA adapters, I highly
  179. recommend the book by Richard Wilton, _Programmer's Guide to PC & PS/2
  180. Video Systems_.  An excellent book if you are doing any kind of video
  181. programming.  For a description of the mouse driver interface, I can
  182. recommend Logitech's Mouse Programmer's Toolkit, Microsoft Press's Mouse
  183. Reference Guide, and Ralf Brown's Interrupt List (updated periodically).
  184. I initially learned the interface to the mouse driver from an article in PC
  185. Magazine (I can't remember what issue), and I use Ralf Brown's Interrupt
  186. List for reference now.
  187.  
  188. 3. Variable and definition reference.
  189. -------------------------------------
  190.  
  191. The following variables and definitions are included in MOU.H:
  192.  
  193. C:      MOUINFOREC
  194.  
  195. Pascal: mouinforectype
  196.  
  197. This is the definition for the structure returned by the functions
  198. MOUpreview() and MOUget().  It contains the following fields:
  199.  
  200.   word buttonstat:  bits in this field indicate what event occurred.  See them
  201.                     below.
  202.   int cx, cy: character coordinates of where this event occurred.
  203.   byte shiftshate:  the status of the shift keys at the time of the event.
  204.                     See definitions below.
  205.  
  206. ---------------------------------------
  207.  
  208. C:      MOUBUFFERSIZE
  209.  
  210. Pascal: MOUBUFFERSIZE
  211.  
  212. This is the size of the mouse buffer.  The buffer is where mouse events are
  213. held for the program until is retrieves them with MOUget().
  214.  
  215. ---------------------------------------
  216.  
  217. C:      MOUSEMOVE, LEFTBPRESS, LEFTBRELEASE, RIGHTBPRESS, RIGHTBRELEASE,
  218.         MIDBPRESS, MIDBRELEASE
  219.  
  220. Pascal: MOUSEMOVE, LEFTBPRESS, LEFTBRELEASE, RIGHTBPRESS, RIGHTBRELEASE,
  221.         MIDBPRESS, MIDBRELEASE
  222.  
  223. These defines are for the field buttonstat in the MOUINFOREC structure.  By
  224. checking the bits of buttonstat, you can find out what event occurred, for
  225. example, "if (m.buttonstat & LEFTBPRESS)" will be true if the event was
  226. caused by the press of the left mouse button.
  227.  
  228. ---------------------------------------
  229.  
  230. C:      LEFTBDOWN, RIGHTBDOWN
  231.  
  232. Pascal: LEFTBDOWN, RIGHTBDOWN
  233.  
  234. These defines are used for the value returned by the function
  235. MOUbuttonstatus().  I.e. "if (MOUbuttonstatus() & LEFTBDOWN)" will be TRUE
  236. if the left mouse button is currently down.
  237.  
  238. ---------------------------------------
  239.  
  240. C:      SHIFT_RIGHTSHIFT, SHIFT_LEFTSHIFT, SHIFT_SHIFT, SHIFT_CTRL, SHIFT_ALT,
  241.         SHIFT_SCROLLLOCK, SHIFT_NUMLOCK, SHIFT_CAPSLOCK, SHIFT_INS
  242.  
  243. Pascal: SHIFT_RIGHTSHIFT, SHIFT_LEFTSHIFT, SHIFT_SHIFT, SHIFT_CTRL, SHIFT_ALT,
  244.         SHIFT_SCROLLLOCK, SHIFT_NUMLOCK, SHIFT_CAPSLOCK, SHIFT_INS
  245.  
  246. These defines are for the shiftstate field in the MOUINFOREC structure.  It
  247. allows you to check for such things as shift-clicks.  I.e.
  248. "if (m.shiftstate & SHIFT_LEFTSHIFT)" will be TRUE if the left shift key
  249. was held down during the mouse event.  SHIFT_SHIFT is defined as both shift
  250. keys.
  251.  
  252. ---------------------------------------
  253.  
  254. C:      word mousehidden;
  255.  
  256. Pascal: mousehidden : word;
  257.  
  258. This variable will be true (non-zero) if the mouse is currently hidden.  It
  259. is undefined if mouseinstalled is false.  Don't write to this variable,
  260. it's just provided for your reference.
  261.  
  262. ---------------------------------------
  263.  
  264. C:      boolean mouseinstalled;
  265.  
  266. Pascal: mouseinstalled : boolean;
  267.  
  268. This variable will be true (non-zero) if a mouse driver is installed and
  269. operating and the mouse routines are active and reading the mouse and
  270. drawing the cursor.  If it is false, the mouse driver routines will not
  271. operate, calling them will do nothing (but calling them is not harmful).
  272.  
  273. ---------------------------------------
  274.  
  275. C:      volatile int mousex, mousey;
  276.  
  277. Pascal  mousex, mousey : integer;
  278.  
  279. These variables hold the current location of the mouse cursor.  They are
  280. updated by the mouse handler.  Note that their value may changed at _any_
  281. time.  Don't depend on them being constant. If you need to reference them,
  282. I recommend declaring a couple of variables to hold their values (i.e. int
  283. x, y;  x = mousex; y = mousey;) and using those instead of mousex and
  284. mousey.  Only reference mousex and mousey when you need to update the
  285. position.
  286.  
  287.  
  288. 4. Function reference.
  289. ----------------------
  290.  
  291. C:      void FAST MOUinit(void);
  292.  
  293. Pascal: procedure MOUinit;
  294.  
  295. This function initializes the mouse routines, checks for presence of the
  296. mouse driver, DESQview and an EGA/VGA.  What it does is described above in
  297. "How does it work?".
  298.  
  299. ---------------------------------------
  300.  
  301. C:      void FAST MOUdeinit(void);
  302.  
  303. Pascal: procedure MOUdeinit;
  304.  
  305. This function will deinitialize the mouse routines.  It will stop the mouse
  306. driver from calling the handler, and erase the mouse cursor.  You can call
  307. MOUinit() if you wish to use the mouse driver routines again. You MUST call
  308. this function before you quit your program.  Failure to do so will most
  309. likely cause your computer to crash next time the mouse is moved.  If you
  310. don't call it, the mouse driver still calls the mouse hander, even after
  311. the program has quit.
  312.  
  313. ---------------------------------------
  314.  
  315. C:      void FAST MOUhide(void);
  316.  
  317. Pascal: procedure MOUhide;
  318.  
  319. This hides the mouse cursor.  The mouse cursor must be hidden with this
  320. function (or MOUconditionalhide() below) before doing any screen updating.
  321. This prevents overwriting the mouse cursor.  The preferred way to hide the
  322. mouse is MOUconditionalhide().  But if you are clearing the screen, or
  323. updating all of it at once, use this function.  This function counts how
  324. many times it has been called, i.e. if you call it twice, you have to call
  325. MOUshow() twice to get the cursor back on the screen.
  326.  
  327. ---------------------------------------
  328.  
  329. C:      void FAST MOUconditionalhide(int x1, int y1, int x2, int y2);
  330.  
  331. Pascal: procedure MOUconditionalhide(x1, y1, x2, y2 : integer);
  332.  
  333. This function hides the mouse automatically if it is in, or is moved in,
  334. the rectangular region defined by this function.  If possible use this
  335. function to hide the mouse, as if the mouse isn't near the area being
  336. updated, it won't 'blink' like it would calling MOUhide().  The coordinates
  337. are zero based and x1 must be <= x2 and y1 must be <= y2.  Call MOUshow()
  338. after you have finished updating the region you defined.  If the mouse was
  339. hidden, MOUshow() will turn it back on.
  340.  
  341. ---------------------------------------
  342.  
  343. C:      void FAST MOUshow(void);
  344.  
  345. Pascal: procedure MOUshow;
  346.  
  347. This turns on the mouse cursor after a previous call to MOUhide() or
  348. MOUconditionalhide().  This function may be called as many times as you
  349. like, once the cursor is not hidden, any other calls will have no effect.
  350.  
  351. ---------------------------------------
  352.  
  353. C:      boolean FAST MOUcheck(void);
  354.  
  355. Pascal: function MOUcheck : boolean;
  356.  
  357. This function returns true (non-zero) if there are events in the buffer, if
  358. not it returns false (zero).
  359.  
  360. ---------------------------------------
  361.  
  362. C:      void FAST MOUpreview(MOUINFOREC *mouinforec);
  363.  
  364. Pascal: procedure MOUpreview(var mouinforec : mouinforectype);
  365.  
  366. This function passes the next event to the MOUINFOREC passed to it.  It
  367. does not remove the event from the buffer.  If there are no events in the
  368. buffer, the MOUINFOREC returned will have the current mouse position in the
  369. cx and cy fields of the MOUINFOREC, the shiftstate field set to the current
  370. state of the shift keys, and the buttonstat field blank (zero, or no
  371. events).
  372.  
  373. ---------------------------------------
  374.  
  375. C:      void FAST MOUget(MOUINFOREC *mouinforec);
  376.  
  377. Pascal: procedure MOUget(var mouinforec : mouinforectype);
  378.  
  379. This function passes the next event to the MOUINFOREC passed to it.  It
  380. will remove the event from the buffer.  If there are no events in the
  381. buffer, the MOUINFOREC returned will have the current mouse position in the
  382. cx and cy fields of the MOUINFOREC, the shiftstate field set to the current
  383. state of the shift keys, and the buttonstat field blank (zero, or no
  384. events).
  385.  
  386. ---------------------------------------
  387.  
  388. C:      word FAST MOUbuttonstatus(void);
  389.  
  390. Pascal: function MOUbuttonstatus : word;
  391.  
  392. This will return the current status of the mouse buttons. It can be
  393. ANDed with LEFTBDOWN, MIDBDOWN or RIGHTBDOWN to see if either button is
  394. currently being held down. This function could be used to detect
  395. dragging of the mouse.
  396.  
  397. ---------------------------------------
  398.  
  399. C:      void FAST MOUsetpos(word x, word y);
  400.  
  401. Pascal: procedure MOUsetpos(x, y : integer);
  402.  
  403. Sets the current mouse position.  Mouse will move to the new coordinates on
  404. the call.  Parameters are character coordinates, not pixel coordinates.
  405.  
  406. 5. The test program.
  407. --------------------
  408.  
  409. Included with the routines is a small test program that will allow you to
  410. see the 'true' mouse cursor (if you have an EGA/VGA adapter).  Included is
  411. a makefile for NDMake and Turbo C/Microsoft C.  The makefile defaults to
  412. Turbo C, you have to make a simple edit for Microsoft C. If you don't have
  413. a makefile, you can compile it like this:
  414.  
  415.   tcc -ml test.c mou.c
  416.  
  417. or under MSC as:
  418.  
  419.   cl /AL test.c mou.c
  420.  
  421. or under Turbo Pascal:
  422.  
  423.   tpc ptest.pas
  424.  
  425. Note: with Turbo C, you will require to have TASM in your path as the
  426. routines have inline assembler in them.  MASM isn't required for MSC (MSC
  427. has a built in assembler, though it's a bit dumb at times).
  428.  
  429. It's a simple program that will tell you the current mouse position and the
  430. status of the mouse buttons.
  431.  
  432. The mouse routines will work in ALL EGA/VGA text modes.  I've run it in
  433. 80x25 and 80x50 mode and the 'true' cursor will be drawn in both those
  434. modes.  My VGA supports a 132x60 mode as well, and the 'true' mouse cursor
  435. works perfectly in that mode as well.
  436.  
  437. The C version of the test program requires ANSI.SYS to be installed.
  438.  
  439. 6. Disclaimer and other stuff.
  440. ------------------------------
  441.  
  442. I originally started working on these routines when I first saw the new
  443. version of Norton's Utilities (version 5.0).  I was impressed with the
  444. 'true' mouse cursor it was drawing in text mode, and wanted to know if I
  445. could write a set of routines to do the same thing.
  446.  
  447. In Jan. of '91, a discussion on the group comp.os.msdos.programmer about the
  448. way Norton does the 'true' mouse cursor arose.  I replied to a message by
  449. Brian K. W. Hook who indicated that he doubted Norton changed the font on
  450. the fly to implement a 'true' mouse cursor in text mode.  He stated he was
  451. 'baffled' by the way that Norton did it.  I stated that Norton did do it by
  452. changing the font on the fly, and that I had written some routines to do it
  453. as well.
  454.  
  455. Brian asked me for the routines, as well as a couple of other users, so I
  456. cleaned them up, made them independent of my text window library (I've
  457. written a library for text window routines that I use in my programs) and
  458. otherwise prepared to unleash them on unsuspecting Usenet victims. :)
  459.  
  460. These routines also illustrate interfacing to mouse driver function 12,
  461. which seems to be a common question on comp.os.msdos.programmer (How to I do
  462. interface to the mouse driver?).
  463.  
  464. I'll supply support for these routines as my time permits, and I can be
  465. reached by any of the following methods of communication:
  466.  
  467. Email:  UUCP:            {uunet,ubc-cs}!van-bc!rsoft!mindlink!a563
  468.         Internet/Usenet: Zoid@mindlink.bc.ca
  469.  
  470.         Zoid@mindlink.bc.ca is preferred.
  471.  
  472. Mail:   #801-9835 King George Hwy.
  473.         Surrey, BC  Canada
  474.         V3T 5H6
  475.  
  476. Phone:  604-585-8844.
  477.  
  478. Duncan Murdoch converted the routines to Turbo Pascal 6.0 for me.  He can
  479. be reached at:
  480.  
  481.   dmurdoch@watstat.waterloo.edu
  482.  
  483. I do hope you enjoy these routines, and have an 'edge' on the competition
  484. by having a flashy 'true' cursor on the EGA/VGA.  Wow!
  485.  
  486.  
  487.  
  488.                                 DISCLAIMER
  489.  
  490.    Dave Kirsch makes no warranty of any kind, either express or implied,
  491.    including but not limited to implied warranties of merchantability
  492.    and fitness for a particular purpose, with respect to this software
  493.    and accompanying documentation.
  494.  
  495.    IN NO EVENT SHALL DAVE KIRSCH BE LIABLE FOR ANY DAMAGES (INCLUDING
  496.    DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
  497.    BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OUT OF THE
  498.    USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF DAVE KIRSCH HAS BEEN
  499.    ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  500.  
  501.    Programmers may incorporate any or all code into their programs,
  502.    giving proper credit within the source. Publication of the
  503.    source routines is permitted so long as proper credit is given
  504.    to Dave Kirsch.
  505.  
  506.                  Copyright (C) 1990, 1991 by Dave Kirsch.
  507.  
  508.  
  509. 7. Modification history.
  510. ------------------------
  511.  
  512. Date      Version
  513. 91-10-25   1.05  Fixed the documentation a bit.
  514.  
  515. 91-03-15   1.04  Added a function to set the current mouse position.  From a
  516.                  suggestion by Gary Tepel.
  517.  
  518. 91-01-27   1.03  Added the Turbo Pascal version and cleaned up the code and
  519.                  documentation.  Fixed so it _does_ work under MSC 6.0.
  520.  
  521. 91-01-17   1.02  Added support for the middle mouse button, from diffs sent
  522.                  to me from acero@quads.uchicago.edu (Tony Acero).
  523.  
  524. 91-01-10   1.01  Fixed bug when referencing POINTS in the mouse handler.
  525.  
  526. 91-01-08   1.00  Initial release.
  527.  
  528. Planned enhancements:
  529.  
  530.   1. It's currently untested with Turbo C++, can anyone verify it works with
  531.      it?  It should.
  532.   2. Functions to redefine the mouse cursor on the fly.
  533.   3. Convert it for use with other C/C++ compilers (i.e. Zortech).
  534.   4. I've had a report or two of a 'grid' appearing with the cursor on Sigma
  535.      VGA cards.  I want to investigate this.
  536.   5. Make it work on Hercules RAMFont.
  537.